package com.example.lock;


import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 *
 * 公司：德迅科技
 * 作者：wangdi
 * 描述：
 * 日期： 2025/11/5
 *
 * @author DEO
 */

public class LockSyncDemo {


    private static final LockedObject LOCKED_OBJECT = new LockedObject();

    private static final AtomicInteger counter = new AtomicInteger(0);



    public static void main(String[] args) throws InterruptedException {
        new LockSyncDemo().testVirtualThinLock();
    }

    public static class LockedObject {
        private int id;
        private String name;
    }

    /**
     * 偏向锁测试
     *
     * @throws InterruptedException
     */
    private void testBiasLock() throws InterruptedException {
        // 1. 等待偏向锁启动延迟（默认4秒，或通过JVM参数取消延迟）
        Thread.sleep(5000);

        CountDownLatch latch = new CountDownLatch(1);

        // 线程A：首次获取锁，使锁偏向于A
        Thread threadA = new Thread(() -> {
            synchronized (LOCKED_OBJECT) {
                System.out.println("【Thread-A】持有锁时的对象头：");
                System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
            }
            latch.countDown(); // 通知主线程A已完成
        }, "Thread-A");
        threadA.start();
        latch.await(); // 等待A执行完毕
        threadA.join(); // 确保A彻底终止（关键：原偏向线程必须退出）

        // 线程B：多次获取锁，触发重偏向
        Thread threadB = new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-B】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }
            }
        }, "Thread-B");
        threadB.start();
        threadB.join();


    }

    /**
     * 虚拟锁测试
     *
     * @throws InterruptedException
     */
    private void testVirtualThinLock() throws InterruptedException {
        // 1. 等待偏向锁启动延迟（默认4秒，或通过JVM参数取消延迟）
        Thread.sleep(5000);

        CountDownLatch latch = new CountDownLatch(1);

        // 线程A：首次获取锁，使锁偏向于A
        Thread threadA = Thread.startVirtualThread(() -> {
            synchronized (LOCKED_OBJECT) {
                System.out.println("【Thread-A】持有锁时的对象头：");
                System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
            }
            latch.countDown(); // 通知主线程A已完成
        });
        latch.await(); // 等待A执行完毕
        threadA.join(); // 确保A彻底终止（关键：原偏向线程必须退出）

        // 线程B：多次获取锁，触发重偏向
        Thread.startVirtualThread(() -> {
            for (int i = 0; i < 30; i++) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-B】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }
            }
        });



    }


    /**
     * 重量级锁测试
     *
     * @throws InterruptedException
     */
    private void testFatLock() throws InterruptedException {
        AtomicInteger counter = new AtomicInteger(0);
        Thread threadA = new Thread(() -> {
            while ( counter.getAndIncrement() < 3) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-A】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println("【Thread-A】结束");
        }, "Thread-A");
        Thread threadB = new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            while ( counter.getAndIncrement() < 20) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-B】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println("【Thread-B】结束");

        }, "Thread-B");
        threadA.start();
        threadB.start();
    }

    /**
     * 虚拟锁重量级锁测试
     *
     * @throws InterruptedException
     */
    private void testVirtualFatLock() throws InterruptedException {
        AtomicInteger counter = new AtomicInteger(0);
        Thread.startVirtualThread(() -> {
            while ( counter.getAndIncrement() < 3) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-A】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println("【Thread-A】结束");
        });

        Thread.startVirtualThread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            while ( counter.getAndIncrement() < 20) {
                synchronized (LOCKED_OBJECT) {
                    System.out.println("【Thread-B】持有锁时的对象头：");
                    System.out.println(ClassLayout.parseInstance(LOCKED_OBJECT).toPrintable());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            System.out.println("【Thread-B】结束");

        });
    }
}
